package com.ruoyi.system.service.impl;

import com.ruoyi.system.domain.OutPutValueInfo;
import com.ruoyi.system.domain.ReservoirInformation;
import com.ruoyi.system.domain.ValueResultBO;
import com.ruoyi.system.domain.vo.OutPutValueVO;
import com.ruoyi.system.mapper.OutPutValueMapper;
import com.ruoyi.system.mapper.ReservoirInformationMapper;
import com.ruoyi.system.service.IReservoirInformationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Array;
import java.util.ArrayList;
import java.util.List;

/**
 * 水库大水面信息Service业务层处理
 *
 * @author ruoyi
 * @date 2024-05-14
 */
@Service
public class ReservoirInformationServiceImpl implements IReservoirInformationService
{
    @Autowired
    private ReservoirInformationMapper reservoirInformationMapper;

    @Autowired
    private OutPutValueMapper outPutValueMapper;

    /**
     * 查询水库大水面信息
     *
     * @param id 水库大水面信息主键
     * @return 水库大水面信息
     */
    @Override
    public ReservoirInformation selectReservoirInformationById(Long id)
    {
        return reservoirInformationMapper.selectReservoirInformationById(id);
    }

    /**
     * 查询水库大水面信息列表
     *
     * @param reservoirInformation 水库大水面信息
     * @return 水库大水面信息
     */
    @Override
    public List<ReservoirInformation> selectReservoirInformationList(ReservoirInformation reservoirInformation)
    {
        return reservoirInformationMapper.selectReservoirInformationList(reservoirInformation);
    }

    /**
     * 新增水库大水面信息
     *
     * @param reservoirInformation 水库大水面信息
     * @return 结果
     */
    @Override
    public int insertReservoirInformation(ReservoirInformation reservoirInformation)
    {
        return reservoirInformationMapper.insertReservoirInformation(reservoirInformation);
    }

    /**
     * 修改水库大水面信息
     *
     * @param reservoirInformation 水库大水面信息
     * @return 结果
     */
    @Override
    public int updateReservoirInformation(ReservoirInformation reservoirInformation)
    {
        return reservoirInformationMapper.updateReservoirInformation(reservoirInformation);
    }

    /**
     * 批量删除水库大水面信息
     *
     * @param ids 需要删除的水库大水面信息主键
     * @return 结果
     */
    @Override
    public int deleteReservoirInformationByIds(Long[] ids)
    {
        return reservoirInformationMapper.deleteReservoirInformationByIds(ids);
    }

    /**
     * 删除水库大水面信息信息
     *
     * @param id 水库大水面信息主键
     * @return 结果
     */
    @Override
    public int deleteReservoirInformationById(Long id)
    {
        return reservoirInformationMapper.deleteReservoirInformationById(id);
    }

    @Override
    public List<OutPutValueVO> queryOutPutValue(OutPutValueInfo outPutValueInfo) {
        if (outPutValueInfo.getBreedArea() == 0 || outPutValueInfo.getYearOfRelease() == 0 || outPutValueInfo.getWaterName() == null){
            throw new RuntimeException("参数错误，请重新输入~");
        }
        // 先将数据插入数据库保存
        outPutValueMapper.insertOutPutValue(outPutValueInfo);
        // 进行计算
        return matchValue(outPutValueInfo);
    }

    private List<OutPutValueVO> matchValue(OutPutValueInfo outPutValueInfo) {
        ValueResultBO resultBO = new ValueResultBO();
        List<OutPutValueVO> resultList = new ArrayList<>();
        for (int i = 1; i < 6; i++) {
            OutPutValueVO outPutValueVO = new OutPutValueVO();
            resultBO = matchWValue(outPutValueInfo,i);
            outPutValueVO.setT(resultBO.getT());
            outPutValueVO.setW(resultBO.getW());
            resultList.add(outPutValueVO);
        }
        return resultList;
    }

    private ValueResultBO matchWValue(OutPutValueInfo outPutValueInfo, int type) {
        // 计算逻辑
        // N = 23.40 * breedArea * 57.5% + (stockSize.lianType * stockDensity.lianType + stockSize.yongType * stockDensity.yongType) * breedArea * 57.5% /1000
        // 如果 type == 1，则 W = N + 57.5% * N * 0.5 + 2403.5 * 1.25 否则 W = 上一次计算出来的W + 57.5% * 上一次计算出来的W * 0.6 + 2403.5 * 1.25
        // T = W * 5
        
        // 先计算N值
        double n = 23.40 * outPutValueInfo.getBreedArea() * 0.575 +
                (outPutValueInfo.getStockSize().getLianType() * outPutValueInfo.getStockDensity().getLianType() +
                        outPutValueInfo.getStockSize().getYongType() * outPutValueInfo.getStockDensity().getYongType()) *
                        outPutValueInfo.getBreedArea() * 0.575 / 1000;
        
        double w;
        if (type == 1) {
            // 第一次计算W
            w = n + 0.575 * n * 0.5 + 2403.5 * 1.25;
        } else {
            // 使用上一次计算的W，这里我们通过递归调用来获取上一次的W值
            ValueResultBO previousResult = matchWValue(outPutValueInfo, type - 1);
            double previousW = previousResult.getW();
            w = previousW + 0.575 * previousW * 0.6 + 2403.5 * 1.25;
        }
        
        double t = w * 5;
        
        // 保留两位小数
        w = Math.round(w * 100.0) / 100.0;
        t = Math.round(t * 100.0) / 100.0;
        
        ValueResultBO valueResultBO = new ValueResultBO();
        valueResultBO.setW(w);
        valueResultBO.setT(t);
        return valueResultBO;
    }
}
